package com.power.sifa.correction.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.aventrix.jnanoid.jnanoid.NanoIdUtils;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.plf.common.domain.PageDataResponse;
import com.plf.common.domain.ResponseDTO;
import com.plf.common.file.service.IFileService;
import com.plf.common.utils.FileUtil;
import com.plf.common.utils.WordUtil;
import com.plf.core.base.model.Ha_attachment;
import com.plf.core.base.service.Ha_attachmentService;
import com.power.sifa.aop.service.SMService;
import com.power.sifa.correction.api.ICrc_personFeign;
import com.power.sifa.correction.listener.Crc_personListener;
import com.power.sifa.correction.model.Crc_person;
import com.power.sifa.correction.model.pageInfo.Crc_personPageInfo;
import com.power.sifa.correction.model.pojo.bo.Crc_personExcelBO;
import com.power.sifa.correction.service.Crc_personService;
import com.power.sifa.util.ExcelCommonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 社区矫正人员信息控制器
 */

@Slf4j
//@PowerLog
@RestController
@Api(value = "Crc_personController", tags = {"社区矫正人员信息"})
public class Crc_personController implements ICrc_personFeign {

    @Resource
    private Crc_personService crc_personService;

    @Resource
    private IFileService fileService;

    @Resource
    private Ha_attachmentService ha_attachmentService;

    @Resource
    private SMService smService;

    /**
     * 申请材料附件生成路径
     */
    @Value("${power.file-path:#{null}}")
    private String filePath;


    @Override
    public ResponseDTO getNextval() {
//        return ResponseDTO.succData(this.crc_personService.getNextval());
        return ResponseDTO.succData(this.crc_personService.getNextval());
    }

    @Override
    @ApiOperation("查询社区矫正人员信息分页列表")
    @SaCheckPermission("crc_person_list")
    public ResponseDTO list(Crc_personPageInfo pageInfo) {
        Assert.notNull(pageInfo, "pageInfo参数不能为空");
        Page<Crc_person> page = this.crc_personService.findAll(pageInfo);
        List list = new ArrayList();
        if (!page.isEmpty()) {
            for (Crc_person crc_person : page) {
                crc_person.geneText();
                list.add(crc_person);
            }
        }
        PageDataResponse p = new PageDataResponse(list, page.getTotalElements(), page.getSize(), pageInfo.getPageNumber() <= 1 ? 1 : pageInfo.getPageNumber());
        return ResponseDTO.succData(p);
    }

    @Override
    @ApiOperation("查看社区矫正人员信息")
    @SaCheckPermission("crc_person_view")
    public ResponseDTO view(String id) {
        Assert.notNull(id, "id不能为空");
        Crc_person crc_person = crc_personService.getById(id);
        if (crc_person != null) {
            crc_person.geneText();
            try {
//                crc_person.setCardno(smService.decrypt(crc_person.getCardno()));
                crc_person.setPhone(smService.encrypt(crc_person.getPhone()));
                crc_person.setName(smService.encrypt(crc_person.getName()));

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ResponseDTO.succData(crc_person);
    }

    @Override
    @ApiOperation("删除社区矫正人员信息")
    @SaCheckPermission("crc_person_del")
    public ResponseDTO delete(String id) {
        Assert.notNull(id, "id不能为空");
        crc_personService.removeById(id);
        return ResponseDTO.succ();
    }

    @Override
    @ApiOperation("保存或修改社区矫正人员信息")
    @SaCheckPermission("crc_person_save")
    public ResponseDTO save(Crc_person crc_person) {
        Assert.notNull(crc_person, "crc_person不能为空");
        // 判断id是否为空，为空则不是新增的数据
        if (org.apache.commons.lang3.StringUtils.isNotBlank(crc_person.getId())) {
            crc_personService.saveOrUpdate(crc_person);
            return ResponseDTO.succ();
        } else {
            // 判断是否有相同的身份证号码存在
            Crc_person person = crc_personService.findByCardNos(crc_person.getCardno());
            if (ObjectUtil.isNull(person)) {
                crc_personService.saveOrUpdate(crc_person);
                return ResponseDTO.succ();
            } else {
                return ResponseDTO.wrap(500, "已存在相同身份证号的社矫人员");
            }
        }
    }

    @Override
    @ApiOperation(value = "批量删除社区矫正人员信息")
    @SaCheckPermission("crc_person_del")
    public ResponseDTO batchDel(String ids) {
        Assert.isTrue(StringUtils.hasText(ids), "ids不能为空");
        List<String> list = Arrays.asList(ids.split(",")).stream().map(s -> s.trim()).collect(Collectors.toList());
        crc_personService.removeByIds(list);
        return ResponseDTO.succ();
    }

    @Override
    @ApiOperation(value = "导出excel")
    @SaCheckPermission("crc_person_list")
    public void output(HttpServletResponse response, Crc_personPageInfo pageInfo) {
        Assert.notNull(pageInfo, "pageInfo不能为空");
        List<Crc_person> personList = this.crc_personService.queryAllList(pageInfo);
        List<Crc_personExcelBO> excelBOList = Crc_personExcelBO.convertListToExcel(personList);
        ExcelCommonUtil.export(response, "社区矫正人员信息模板", excelBOList, Crc_personExcelBO.class);
    }

    @Override
    @ApiOperation(value = "导出excel模板")
    public void exportExcelTemplate(HttpServletResponse response) {
        ExcelCommonUtil.export(response, "社区矫正人员信息模板", null, Crc_personExcelBO.class);
    }

    @Override
    @ApiOperation(value = "导入excel")
    public ResponseDTO importExcel(MultipartFile file) throws IOException {
        Assert.notNull(file, "file不能为空");
        try {
            EasyExcel.read(file.getInputStream(), Crc_personExcelBO.class, new Crc_personListener(crc_personService, smService))
                    .sheet().doRead();
            return ResponseDTO.succ();
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseDTO.wrap(500, "导入excel失败");
        }
    }

    /**
     * 社区矫正人员信息分页查询
     *
     * @param pageInfo
     * @return
     */
    @Override
    public ResponseDTO pageQuery(Crc_personPageInfo pageInfo) {
        Assert.notNull(pageInfo, "pageInfo参数不能为空");
        return ResponseDTO.succData(crc_personService.pageQuery(pageInfo));
    }

    /**
     * 全部社矫人员信息查询
     *
     * @return
     */
    @Override
    public ResponseDTO findAllPerson(List<String> deptIds) {
        return ResponseDTO.succData(crc_personService.findAllFocus(deptIds));
    }

    /**
     * 全部社矫司法所信息查询
     *
     * @return
     */
    @Override
    public ResponseDTO findAllLawDeparts() {
        return ResponseDTO.succData(crc_personService.findAllLawDeparts());
    }

    @Override
    public ResponseDTO queryById(String id) {
        return ResponseDTO.succData(crc_personService.queryById(id));
    }

    @Override
    public ResponseDTO getList() {
        return ResponseDTO.succData(this.crc_personService.getList());
    }

    @Override
    public void downloadPersonPhoto(List<String> personIds, HttpServletResponse response) throws Exception {
        Assert.notNull(personIds, "人员id不能为空");
        // 获取全部的人员
        List<Crc_person> personList = this.crc_personService.findByPersonIds(personIds);
        if (CollUtil.isNotEmpty(personList)) {
            File rootFile = new File(this.filePath + "/" + NanoIdUtils.randomNanoId());
            rootFile.mkdirs();

            List<String> attachMentId = personList.stream().map(Crc_person::getAvatar).distinct().collect(Collectors.toList());
            Map<String, Ha_attachment> ha_attachmentMap = ha_attachmentService.getHa_attachmentMapByIds(attachMentId);

            try {
                for (Crc_person personInfo : personList) {
                    // 在本地创建材料文件
                    String avatarUrl = personInfo.getAvatarUrl();
                    if (org.apache.commons.lang3.StringUtils.isNotEmpty(avatarUrl) && ha_attachmentMap.containsKey(personInfo.getAvatar())) {
                        String fileType = avatarUrl.substring(avatarUrl.lastIndexOf("."));
                        String fileName = personInfo.getId() + "-" + personInfo.getName() + "-" + personInfo.getCardno();
                        File file = new File(rootFile.getAbsolutePath() + "/" + fileName + fileType);

                        Ha_attachment attachment = ha_attachmentMap.get(personInfo.getAvatar());
                        InputStream photoInputStream = fileService.getStream(attachment.getBucket(), attachment.getPath());
                        if (ObjectUtil.isNotNull(photoInputStream)) {
                            byte[] photoByte = IOUtils.toByteArray(photoInputStream);
                            try (FileOutputStream fos = new FileOutputStream(file)) {
                                fos.write(photoByte);
                            } catch (IOException e) {
                                log.error("图片流转换异常 {}", e.getMessage());
                            }
                        }
                    }
                }
                // 压缩文件为zip格式
                FileUtil.toZip(rootFile.getAbsolutePath(), true);
                // 下载材料文件
                FileUtil.download(response, rootFile.getAbsolutePath() + ".zip", rootFile.getAbsolutePath() + ".zip");
            } catch (Exception e) {
                e.printStackTrace();
                log.error("导出社矫布控人员照片失败 {}", e.getMessage());
            } finally {
                // 删除材料文件
                FileUtil.delDir(rootFile);
                FileUtil.delDir(new File(rootFile.getAbsolutePath() + ".zip"));
            }
        }
    }

    /*@Override
    public ResponseEntity<byte[]> downloadPersonWordOld(List<String> personIds, HttpServletResponse response) throws Exception {
        Assert.notNull(personIds, "人员id不能为空");
        // 获取全部的人员
        List<Crc_person> personList = this.crc_personService.findByPersonIds(personIds);
        if (CollUtil.isNotEmpty(personList)) {
            personList = personList.stream().filter(el -> ObjectUtil.isNotNull(el.getAvatarUrl())).collect(Collectors.toList());
            List<File> tempFileList = new ArrayList<>();
            try {
                List<String> attachMentId = personList.stream().map(Crc_person::getAvatar).distinct().collect(Collectors.toList());
                Map<String, Ha_attachment> ha_attachmentMap = ha_attachmentService.getHa_attachmentMapByIds(attachMentId);
                // 遍历人员数据
                List<Object[]> wordTableList = new ArrayList<>();
                Map tableData = new HashMap();
                Map<String, WordUtil.Img> imgMapData = new HashMap();
                WordUtil wordUtil = new WordUtil("CorrectPersonInfo.docx");
                final String imgKey = "$img";
                for (int index = 0; index < personList.size(); index++) {
                    Crc_person personInfo = personList.get(index);
                    personInfo.setCardno(smService.decrypt(personInfo.getCardno()));
                    Ha_attachment attachment = ha_attachmentMap.get(personInfo.getAvatar());
                    try {
                        InputStream photoInputStream = fileService.getStream(attachment.getBucket(), attachment.getPath());
                        String fileType = personInfo.getAvatarUrl().substring(personInfo.getAvatarUrl().lastIndexOf("."));
                        File tempFile = File.createTempFile(attachment.getId(), fileType);

                        if (ObjectUtil.isNotNull(photoInputStream)) {
                            byte[] photoByte = IOUtils.toByteArray(photoInputStream);
                            FileOutputStream fos = null;
                            try {
                                fos = new FileOutputStream(tempFile);
                                fos.write(photoByte);
                            } catch (IOException e) {
                                log.error("图片流转换异常 {}", e.getMessage());
                            } finally {
                                fos.close();
                            }
                        }
                        FileInputStream fileInputStream = new FileInputStream(tempFile);
                        WordUtil.Img img = wordUtil.new Img(fileInputStream);
                        final String imgRandomKey = imgKey + "{img" + index + "}";
                        Object[] wordTable = new Object[]{
                                personInfo.getId(),
                                personInfo.getName(),
                                personInfo.getCardno(),
                                imgRandomKey
                        };
                        imgMapData.put("img" + index, img);
                        tempFileList.add(tempFile);
                        wordTableList.add(wordTable);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }

                tableData.put("list", wordTableList);
                tableData.put("fileList", tableData);

                Map<String, Object> tableForm = new HashMap();
                SimpleDateFormat format = new SimpleDateFormat("yyyy年M月");
                tableForm.put("date", format.format(new Date()));
                wordUtil.replaceParams(tableForm);
                wordUtil.insertTable(tableData);
                OutputStream os = wordUtil.createWord();
                InputStream tempInputStream = new ByteArrayInputStream(((ByteArrayOutputStream) os).toByteArray());

                WordUtil wordUtil2 = new WordUtil();
                XWPFDocument doc = new XWPFDocument(tempInputStream);
                wordUtil2.setDoc(doc);
                wordUtil2.replaceTableImg(imgMapData);
                OutputStream newOs = wordUtil2.createWord();

                InputStream inputStream = new ByteArrayInputStream(((ByteArrayOutputStream) newOs).toByteArray());
                HttpHeaders heads = new HttpHeaders();
                heads.add(HttpHeaders.CONTENT_TYPE, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
                // 输入流转换为字节流
                byte[] buffer = FileCopyUtils.copyToByteArray(inputStream);
                ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(buffer, heads, HttpStatus.OK);
                return responseEntity;
            } catch (Exception e) {
                e.printStackTrace();
                log.error("导出社矫布控人员信息失败 {}", e.getMessage());
            } finally {
                if (CollUtil.isNotEmpty(tempFileList)) {
                    tempFileList.stream().forEach(file -> file.deleteOnExit());
                }
            }
        }
        return null;
    }*/

    @Override
    public ResponseEntity<byte[]> downloadPersonWord(List<String> personIds, HttpServletResponse response) {
        Assert.notNull(personIds, "人员id不能为空");
        try {
            Map<String, Object> params = new HashMap<>();
            List<Crc_person> personList = this.crc_personService.findByPersonIds(personIds);
//            personList.stream().forEach(person -> {
//                try {
//                    person.setName(smService.encrypt(person.getName()));
////                    person.setCardno(smService.decrypt(person.getCardno()));
//                } catch (Exception e) {
//                    log.error("身份证号码异常：{}", e.getMessage());
//                    e.printStackTrace();
//                }
//            });
            if (CollUtil.isEmpty(personList)) {
                return null;
            }

            params.put("fileList", personList);

            SimpleDateFormat format = new SimpleDateFormat("yyyy年M月");
            String time = format.format(new Date());
            params.put("date", time);

            Configure tables = Configure.builder()
                    .bind("fileList", new LoopRowTableRenderPolicy())
                    .build();

            org.springframework.core.io.Resource resource = new ClassPathResource("template-word/" + "CorrectPersonInfo.docx");
            XWPFTemplate template = XWPFTemplate.compile(resource.getInputStream(), tables).render(params);

            // 将文档内容写入 ByteArrayOutputStream
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            template.write(baos);
            template.close(); // 关闭模板

            // 将文件内容转换为byte数组
            byte[] bytes = baos.toByteArray();

            // 设置响应头，注意这里使用了编码后的文件名
            HttpHeaders heads = new HttpHeaders();
            heads.add(HttpHeaders.CONTENT_TYPE, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");

            ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, heads, HttpStatus.OK);
            return responseEntity;
        } catch (IOException e) {
            log.error("生成word异常{}", e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            log.error("下载异常{}", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

}
